package middleware

import (
	"admin-nexus-backend/internal/model"
	"admin-nexus-backend/internal/service"
	"strings"
	"time"

	"github.com/gin-gonic/gin"
)

// OperationLogMiddleware 操作日志中间件
type OperationLogMiddleware struct {
	logService *service.UserOperationLogService
}

// NewOperationLogMiddleware 创建操作日志中间件
func NewOperationLogMiddleware(logService *service.UserOperationLogService) *OperationLogMiddleware {
	return &OperationLogMiddleware{
		logService: logService,
	}
}

// OperationLog 操作日志中间件
// 记录用户的操作日志（异步记录，不阻塞请求）
func (m *OperationLogMiddleware) OperationLog() gin.HandlerFunc {
	return func(c *gin.Context) {
		// 处理请求
		c.Next()

		// 只记录已认证用户的请求
		userID := GetUserID(c)
		if userID == 0 {
			return
		}

		// 获取请求信息
		method := c.Request.Method
		path := c.Request.URL.Path
		query := c.Request.URL.RawQuery
		ip := c.ClientIP()
		userAgent := c.Request.UserAgent()

		// 构建完整URL
		url := path
		if query != "" {
			url = path + "?" + query
		}

		// 生成操作标题（根据路径和方法）
		title := m.generateTitle(method, path)

		// 异步记录日志（不阻塞请求）
		go func() {
			log := &model.UserOperationLog{
				UserID:    userID,
				Title:     title,
				URL:       url,
				IP:        ip,
				Method:    method,
				UserAgent: userAgent,
				CreatedAt: time.Now(),
			}
			_ = m.logService.CreateLog(log)
		}()
	}
}

// generateTitle 根据请求方法和路径生成操作标题
func (m *OperationLogMiddleware) generateTitle(method, path string) string {
	// 移除 /api/v1 前缀
	path = strings.TrimPrefix(path, "/api/v1")
	path = strings.TrimPrefix(path, "/api")

	// 根据路径和方法生成标题
	parts := strings.Split(strings.Trim(path, "/"), "/")
	if len(parts) == 0 {
		return method + " " + path
	}

	// 处理常见的操作类型
	var title string
	switch method {
	case "GET":
		if len(parts) > 1 && parts[len(parts)-1] != "" {
			// 获取详情
			title = "查看"
		} else {
			// 获取列表
			title = "查看列表"
		}
	case "POST":
		title = "新增"
	case "PUT":
		title = "更新"
	case "DELETE":
		title = "删除"
	case "PATCH":
		title = "修改"
	default:
		title = method
	}

	// 根据路径生成模块名称
	moduleName := m.getModuleName(parts)
	if moduleName != "" {
		title = moduleName + " / " + title
	} else {
		// 如果没有匹配到模块，使用路径的最后一部分
		if len(parts) > 0 {
			title = parts[len(parts)-1] + " / " + title
		}
	}

	// 特殊处理登录
	if strings.Contains(path, "/login") {
		title = "登录"
	}

	return title
}

// getModuleName 根据路径获取模块名称
func (m *OperationLogMiddleware) getModuleName(parts []string) string {
	if len(parts) == 0 {
		return ""
	}

	// 模块名称映射
	moduleMap := map[string]string{
		"users":               "用户管理",
		"user":                "个人中心",
		"roles":               "角色管理",
		"organizations":       "组织管理",
		"permissions":         "权限管理",
		"cities":              "城市管理",
		"teachers":            "教师管理",
		"courses":             "课程管理",
		"course-categories":   "课程分类",
		"course-materials":    "课程素材",
		"member-cards":        "会员卡管理",
		"redemptions":         "兑换管理",
		"competitions":        "比赛管理",
		"stages":              "阶段管理",
		"advancement-results": "晋级管理",
		"exam-rooms":          "考场管理",
		"poster-persons":      "海报人员",
		"poster-certificates": "证书管理",
		"dicts":               "字典管理",
		"attachments":         "附件管理",
		"auth":                "认证",
	}

	// 查找第一个匹配的模块
	for _, part := range parts {
		if moduleName, ok := moduleMap[part]; ok {
			return moduleName
		}
	}

	return ""
}
